home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / solaris2 / book / applets / crosswor / crosswor.jav < prev    next >
Encoding:
Text File  |  1995-09-16  |  22.2 KB  |  863 lines

  1. //-------------------------------------------------------
  2. //
  3. // Written by Carl Haynes
  4. //
  5. // Submitted to Sun Microsystems for their
  6. // java.applet.Applet Contest 8/31/95
  7. //
  8. //--------------------------------------------------------
  9.  
  10. import java.awt.*;
  11.  
  12. public class crossword extends java.applet.Applet {
  13.     final    static    int    kAppWidth     = 500;
  14.     final    static    int    kAppHeight     = 550;
  15.  
  16.     final    static    int    kBlockWidth    = 30;
  17.     final    static    int    kBlockHeight    = 30;
  18.  
  19.     final    static    int    kBlocksWide    = 15;
  20.     final    static    int    kBlocksHigh    = 15;
  21.     final     static    int    kButtonWidth    = 100;
  22.     final     static    int    kButtonHeight    = 25;
  23.  
  24.     final    static    int    kUp = 0;
  25.     final    static    int    kDown = 1;
  26.  
  27.     final static     int kAcross = 0;
  28.  
  29.     final static int kPadding =    20;
  30.     final static int kQuestionAreaHeight = 40;
  31.  
  32.     int gDirection = kAcross;
  33.     int gCurX    = 0;
  34.     int    gCurY    = 0;
  35.  
  36.     int        clipLeft = -1;
  37.     int        clipTop = -1;
  38.     int        clipWidth = -1;
  39.     int         clipHeight = -1;
  40.  
  41.     int        gBlockMinY    = 0;
  42.     int        gBlockMaxY     = 0;
  43.     int        gBlockMinX = 0;
  44.     int        gBlockMaxX    = 0;
  45.  
  46.     int        gOldBlockMinY    = 0;
  47.     int        gOldBlockMaxY     = 0;
  48.     int        gOldBlockMinX = 0;
  49.     int        gOldBlockMaxX    = 0;
  50.  
  51.     String    letters[] = {    "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
  52.                 "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
  53.  
  54.     /*---------------------------------------------------------------*/
  55.     /*---------------------------------------------------------------*/
  56.  
  57.     final static int     layout[][] = {
  58.     {1, 2, 3, -1, -1, 4, 5, 6, 7, -1, -1, 8, 9, 10, -1},
  59.     {11, 00, 00, 12, -1, 13, 00, 00, 00, -1, 14, 00, 00, 00, 15},
  60.     {16, 00, 00, 00, -1, 17, 00, 00, 00, -1, 18, 00, 00, 00, 00},
  61.     {-1, 19, 00, 00, 20, 00, -1, 21, 00, 22, 00, -1, 23, 00, 00},
  62.     {-1, 24, 00, 00, 00, 00, -1, -1, -1, 25, 00, 26, -1, -1, -1},
  63.     {-1, -1, -1, -1, 27, 00, 28, 29, -1, 30, 00, 00, 31, 32, -1},
  64.     {33, 34, 35, 36, 00, -1, 37, 00, 38, 00, -1, 39, 00, 00, 40},
  65.     {41, 00, 00, 00, -1, -1, 42, 00, 00, -1, -1, 43, 00, 00, 00},
  66.     {44, 00, 00, 00, -1, 45, 00, 00, 00, -1, 46, 00, 00, 00, 00},
  67.     {-1, 47, 00, 00, 48, 00, -1, 49, 00, 50, 00, -1, -1, -1, -1},
  68.     {-1, -1, -1, 51, 00, 00, -1, -1, -1, 52, 00, 53, 54, 55, -1},
  69.     {56, 57, 58, -1, 59, 00, 60, 61, -1, 62, 00, 00, 00, 00, -1},
  70.     {63, 00, 00, 64, 00, -1, 65, 00, 66, 00, -1, 67, 00, 00, 68},
  71.     {69, 00, 00, 00, 00, -1, 70, 00, 00, 00, -1, 71, 00, 00, 00},
  72.     {-1, 72, 00, 00, -1, -1, 73, 00, 00, 00, -1, -1, 74, 00, 00}
  73.     };
  74.  
  75.  
  76.     final static String answers[][] = {
  77.     {"G", "A", "D", " ", " ", "C", "R", "A", "B", " ", " ", "B", "A", "D", " "},
  78.     {"A", "B", "E", "D", " ", "A", "U", "R", "A", " ", "B", "A", "B", "E", "L"},
  79.     {"G", "A", "M", "E", " ", "G", "E", "A", "R", " ", "A", "R", "E", "N", "A"},
  80.     {" ", "C", "O", "V", "E", "N", " ", "B", "E", "E", "N", " ", "L", "E", "G"},
  81.     {" ", "A", "S", "I", "D", "E", " ", " ", " ", "G", "A", "B", " ", " ", " "},
  82.     {" ", " ", " ", " ", "D", "Y", "A", "D", " ", "A", "L", "L", "A", "H", " "},
  83.     {"C", "A", "C", "A", "O", " ", "B", "E", "A", "D", " ", "A", "D", "A", "M"},
  84.     {"A", "M", "O", "K", " ", " ", "B", "I", "G", " ", " ", "D", "I", "K", "E"},
  85.     {"B", "I", "D", "E", " ", "D", "A", "C", "E", " ", "B", "E", "T", "E", "L"},
  86.     {" ", "D", "E", "L", "A", "Y", " ", "E", "S", "A", "U", " ", " ", " ", " "},
  87.     {" ", " ", " ", "A", "R", "K", " ", " ", " ", "B", "R", "E", "A", "D", " "},
  88.     {"J", "A", "G", " ", "D", "E", "A", "F", " ", "A", "P", "P", "L", "E", " "},
  89.     {"A", "B", "O", "V", "O", " ", "B", "L", "O", "C", " ", "E", "L", "L", "S"},
  90.     {"B", "U", "Y", "E", "R", " ", "B", "E", "A", "U", " ", "E", "A", "V", "E"},
  91.     {" ", "T", "A", "T", " ", " ", "E", "A", "R", "S", " ", " ", "Y", "E", "A"}
  92.     };
  93.  
  94.  
  95.  
  96.     final static String gQuestionsAcross[] = {
  97.     "",            //  0
  98.     "Goad for driving cattle", // 1
  99.     "",               // 2
  100.     "",               // 3
  101.     "Crustacean",           // 4
  102.     "",               // 5
  103.     "",               // 6
  104.     "",               // 7
  105.     "Not good",           // 8
  106.     "",               // 9
  107.     "",               // 10
  108.     "In bed",           // 11
  109.     "",               // 12
  110.     "Distinctive quality",       // 13
  111.     "Confused mixture of sounds", // 14
  112.     "",                  // 15
  113.     "Amusement",              // 16
  114.     "Equipment",              // 17
  115.     "Area used for sports",          // 18
  116.     "Assembly of witches",          // 19
  117.     "",                  // 20
  118.     "Part of verb to be",          // 21
  119.     "",                  // 22
  120.     "Lower limb",              // 23
  121.     "To one side",              // 24
  122.     "Chatter",              // 25
  123.     "",                  // 26
  124.     "Group of two",              // 27
  125.     "",                  // 28
  126.     "",                  // 29
  127.     "Supreme Being",          // 30
  128.     "",                  // 31
  129.     "",                  // 32
  130.     "Source of cocoa",          // 33
  131.     "",                  // 34
  132.     "",                  // 35
  133.     "",                  // 36
  134.     "Glass ornament",          // 37
  135.     "",                  // 38
  136.     "First man",              // 39
  137.     "",                  // 40
  138.     "Diventare pazzo",          // 41
  139.     "Large",              // 42
  140.     "Embankment",              // 43
  141.     "Remain",              // 44
  142.     "Fresh-water fish",          // 45
  143.     "East Indian pepper plant",   // 46
  144.     "Postpone",              // 47
  145.     "",                  // 48
  146.     "Son of Isaac and Rebekah",   // 49
  147.     "",                  // 50
  148.     "Vessel built by Noah",          // 51
  149.     "Baked dough",              // 52
  150.     "",                  // 53
  151.     "",                  // 54
  152.     "",                  // 55
  153.     "Sharp projection",          // 56
  154.     "",                  // 57
  155.     "",                  // 58
  156.     "Deprived of the sense of hearing", // 59
  157.     "",                    // 60
  158.     "",                    // 61
  159.     "Edible fruit",                // 62
  160.     "From the beginning",            // 63
  161.     "",                    // 64
  162.     "Cartel",                // 65
  163.     "",                    // 66
  164.     "Old cloth measures",            // 67
  165.     "",                    // 68
  166.     "Purchaser",                // 69
  167.     "Sweetheart",                // 70
  168.     "Overhanging lower edge of a roof", // 71
  169.     "Make lace",                // 72
  170.     "Hearing organs",            // 73
  171.     "Affirmative reply"            // 74
  172.     };
  173.  
  174.  
  175.     final static String gQuestionsDown[] = {
  176.     "",            //  0
  177.     "Bavaglio",        // 1
  178.     "Manila hemp plant",    // 2
  179.     "The common people",    // 3
  180.     "U.S. film actor",    // 4
  181.     "Regret",        // 5
  182.     "Bedouin",        // 6
  183.     "Uncover",        // 7
  184.     "Ingot",        // 8
  185.     "Second son of Adam and Eve", // 9
  186.     "Sandy tract",              // 10
  187.     "",                  // 11
  188.     "Hindu mother goddess",          // 12
  189.     "",                  // 13
  190.     "Trite",              // 14
  191.     "Fall behind",              // 15
  192.     "",                  // 16
  193.     "",                  // 17
  194.     "",                  // 18
  195.     "",                  // 19
  196.     "Root of the taro",          // 20
  197.     "",                  // 21
  198.     "Mild oath",              // 22
  199.     "",                  // 23
  200.     "",                  // 24
  201.     "",                  // 25
  202.     "Part of an ice skate",          // 26
  203.     "",                  // 27
  204.     "Title of respect for God",   // 28
  205.     "Free of ice",              // 29
  206.     "",                  // 30
  207.     "Entrance",              // 31
  208.     "Codlike fish",              // 32
  209.     "Taxicab",              // 33
  210.     "Among",              // 34
  211.     "Message symbols",          // 35
  212.     "Pack leader",              // 36
  213.     "",                  // 37
  214.     "Matures",              // 38
  215.     "",                  // 39
  216.     "Honey",              // 40
  217.     "",                  // 41
  218.     "",                  // 42
  219.     "",                  // 43
  220.     "",                  // 44
  221.     "Female homosexual",          // 45
  222.     "Relieve gas",              // 46
  223.     "",                  // 47
  224.     "Zeal",                  // 48
  225.     "",                  // 49
  226.     "Calculating device",          // 50
  227.     "",                  // 51
  228.     "",                  // 52
  229.     "Fencing sword",          // 53
  230.     "Alleviate",              // 54
  231.     "Research deeply",          // 55
  232.     "Punch",              // 56
  233.     "Adjoin",              // 57
  234.     "Spanish painter",          // 58
  235.     "",                  // 59
  236.     "French clergyman",          // 60
  237.     "Bloodsucking insect",          // 61
  238.     "",                  // 62
  239.     "",                  // 63
  240.     "Veterinarian",              // 64
  241.     "",                  // 65
  242.     "Lever for rowing",          // 66
  243.     "",                  // 67
  244.     "Ocean"                  // 68
  245.     };
  246.  
  247.     /*---------------------------------------------------------------*/
  248.  
  249.     String gGuesses[][] = new String[kBlocksWide][kBlocksHigh];
  250.  
  251.     boolean    gUpdateActiveAreaFlag = false;
  252.     boolean    gChangedActiveAreaFlag = false;
  253.  
  254.     Font buttonFont = null;
  255.     Font tileFont = null;
  256.  
  257.     public void init() {
  258.     int viewWidth;
  259.     int left, top;
  260.     
  261.     resize((kBlocksWide * kBlockWidth) + (kPadding * 2), (kBlocksHigh * kBlockHeight) + (kPadding * 3) + kQuestionAreaHeight);
  262.     
  263.     NewGame();
  264.     
  265.     
  266.     buttonFont = new java.awt.Font("Courier", Font.PLAIN, 12);
  267.     tileFont = new java.awt.Font("Helvetica", Font.PLAIN, 36);
  268.     
  269.     }
  270.  
  271.     /*---------------------------------------------------------------*/
  272.  
  273.     public void NewGame() {
  274.     for (int j = 0 ; j < kBlocksHigh ; j++) {
  275.         for (int i = 0 ; i < kBlocksWide ; i++) {
  276.         gGuesses[i][j] = "";    
  277.         }
  278.     }
  279.  
  280.     gOldBlockMinY    = 0;
  281.     gOldBlockMaxY     = 0;
  282.     gOldBlockMinX = 0;
  283.     gOldBlockMaxX    = 0;
  284.  
  285.     gDirection = kAcross;
  286.     gCurX = 0;
  287.     gCurY = 0;
  288.     SetActiveBlock(gCurX, gCurY, gDirection);
  289.  
  290.     }
  291.  
  292.     /*----------------------------------------------*/
  293.  
  294.     public void paint(Graphics g) {
  295.     int left = 0;
  296.     int right = kAppWidth - 1;
  297.     int top = 0;
  298.     int bottom = kAppHeight - 1;
  299.     int tempLeft = 0;
  300.     int tempRight = 0;
  301.     int tempTop = 0;
  302.     int    viewWidth;
  303.     int    viewHeight;
  304.     int buttonWidth = 0;
  305.     int buttonHeight = 0;
  306.     int buttonLeft = 0;
  307.     int buttonTop = 0;
  308.     int tileLeft;
  309.     int tileTop;
  310.     
  311.     Font f = new java.awt.Font("Helvetica", 0, 12);
  312.     g.setFont(f);
  313.     
  314.     Font numFont = new java.awt.Font("Helvetica", 0, 10);
  315.     
  316.     Font answerFont = new java.awt.Font("Helvetica", 0, 18);
  317.     Font questionFont = new java.awt.Font("Courier", 0, 24);
  318.     Font questionFont18 = new java.awt.Font("Courier", 0, 18);
  319.  
  320.     FontMetrics answerFontMetrics = g.getFontMetrics(answerFont);
  321.     FontMetrics questionFontMetrics = g.getFontMetrics(questionFont);
  322.     FontMetrics questionFont18Metrics = g.getFontMetrics(questionFont18);
  323.     
  324.     g.setColor(Color.lightGray);
  325.     g.draw3DRect(0, 0, size().width - 1, size().height - 1, true);
  326.     
  327.     viewWidth = kBlocksWide * kBlockWidth;
  328.     viewHeight = kBlocksHigh * kBlockHeight;
  329.     
  330.     
  331.     top = kPadding;
  332.     left = (size().width / 2) - (viewWidth / 2);
  333.     g.setColor(Color.white);
  334.     g.fill3DRect(left, top, viewWidth, kQuestionAreaHeight, false);
  335.     
  336.     g.setFont(f);
  337.     String s = new String(    String.valueOf(layout[gBlockMinY][gBlockMinX]));
  338.     s = s.concat(" - ");
  339.     if (gDirection == kAcross)
  340.         s = s.concat("across");
  341.     else
  342.         s = s.concat("down");
  343.     g.drawString(s, left + 5, top + 12);    
  344.     g.setFont(questionFont);
  345.     if (gDirection == kAcross) {
  346.         Font userFont = questionFont;
  347.     
  348.         if (questionFontMetrics.stringWidth(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]) > viewWidth - 4)
  349.         {
  350.         userFont = questionFont18;
  351.         g.setFont(questionFont18);
  352.         }
  353.     
  354.         g.drawString(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]], 
  355.              (size().width / 2) - (g.getFontMetrics().stringWidth(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]) / 2), 
  356.              (top + kQuestionAreaHeight) - 8);
  357.     
  358.     }    
  359.     else {
  360.         Font userFont = questionFont;
  361.     
  362.         if (questionFontMetrics.stringWidth(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]) > viewWidth - 4)
  363.         {
  364.         userFont = questionFont18;
  365.         g.setFont(questionFont18);
  366.         }
  367.     
  368.         g.drawString(gQuestionsDown[layout[gBlockMinY][gBlockMinX]], 
  369.              (size().width / 2) - (g.getFontMetrics().stringWidth(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]) / 2), 
  370.              (top + kQuestionAreaHeight) - 8);
  371.     }
  372.  
  373.     left = (size().width / 2) - (viewWidth / 2);
  374.     top = (kPadding * 2) + kQuestionAreaHeight; 
  375.  
  376.     for (int j = 0 ; j < kBlocksHigh ; j++) {
  377.         for (int i = 0 ; i < kBlocksWide ; i++) {
  378.         tempLeft = left + (i * kBlockWidth);
  379.         tempTop = top + (j * kBlockHeight);
  380.     
  381.         if (InActiveBlock(i, j)) {
  382.             if (i == gCurX && j == gCurY)
  383.             g.setColor(Color.cyan);
  384.             else
  385.             g.setColor(Color.yellow);
  386.             g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight);
  387.         }
  388.         else {
  389.             g.setColor(Color.white);
  390.             g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight);
  391.         }
  392.     
  393.         g.setColor(Color.black);
  394.         g.drawRect(tempLeft, tempTop, kBlockWidth , kBlockHeight );
  395.     
  396.         if (layout[j][i] == -1){
  397.             g.setColor(Color.black);
  398.             g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight);
  399.         }
  400.         else if (layout[j][i] != 0) {
  401.             String numStr = String.valueOf(layout[j][i]);
  402.         
  403.             g.setFont(numFont);
  404.             g.drawString(numStr, tempLeft + 4 , tempTop + 10);
  405.         
  406.         }
  407.     
  408.         // -- put in text if needed
  409.         
  410.         if (layout[j][i] != -1) {
  411.             if (gGuesses[i][j].length() != 0) {
  412.             int sWidth = 0;
  413.             
  414.             if (gGuesses[i][j].equalsIgnoreCase(answers[j][i]) == false)
  415.                 g.setColor(Color.red);
  416.             else
  417.                 g.setColor(Color.black);
  418.             
  419.             sWidth = answerFontMetrics.stringWidth(gGuesses[i][j]);
  420.             g.setFont(answerFont);
  421.             g.drawString( gGuesses[i][j], tempLeft + ((kBlockWidth / 2) - (sWidth / 2)), (tempTop + kBlockHeight) - 6);
  422.             }
  423.             
  424.         }    
  425.         
  426.         }
  427.     }
  428.     }
  429.  
  430.     /*----------------------------------------------*/
  431.  
  432.     void PaintWord(Graphics g, int minX, int maxX, int minY, int maxY) {
  433.     int viewWidth = kBlocksWide * kBlockWidth;
  434.     int viewHeight = kBlocksHigh * kBlockHeight;
  435.     int left = (size().width / 2) - (viewWidth / 2);
  436.     int top = (kPadding * 2) + kQuestionAreaHeight; 
  437.     int tempLeft = 0;
  438.     int tempRight = 0;
  439.     int tempTop = 0;
  440.     
  441.     left += (minX * kBlockWidth);
  442.     top += (minY * kBlockHeight);
  443.     /*
  444.     g.clipRect(    left, top, 
  445.            (kBlockWidth * (maxX - minX)) + kBlockWidth, 
  446.            (kBlockHeight * (maxY - minY)) + kBlockHeight);
  447.            */
  448.            
  449.            
  450.     Font f = new java.awt.Font("Helvetica", 0, 12);
  451.     g.setFont(f);
  452.            
  453.     Font numFont = new java.awt.Font("Helvetica", 0, 10);
  454.            
  455.     Font answerFont = new java.awt.Font("Helvetica", 0, 18);
  456.     FontMetrics answerFontMetrics = g.getFontMetrics(answerFont);
  457.            
  458.     viewWidth = kBlocksWide * kBlockWidth;
  459.     viewHeight = kBlocksHigh * kBlockHeight;
  460.            
  461.     left = (size().width / 2) - (viewWidth / 2);
  462.     top = (kPadding * 2) + kQuestionAreaHeight; 
  463.            
  464.     for (int j = minY ; j <= maxY ; j++) {
  465.         for (int i = minX ; i <= maxX ; i++) {
  466.         tempLeft = left + (i * kBlockWidth);
  467.         tempTop = top + (j * kBlockHeight);
  468.                
  469.         if (InActiveBlock(i, j)) {
  470.             if (i == gCurX && j == gCurY)
  471.             g.setColor(Color.cyan);
  472.             else
  473.             g.setColor(Color.yellow);
  474.             g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight);
  475.         }
  476.         else {
  477.             g.setColor(Color.white);
  478.             g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight);
  479.         }
  480.                
  481.         g.setColor(Color.black);
  482.         g.drawRect(tempLeft, tempTop, kBlockWidth , kBlockHeight );
  483.                
  484.         if (layout[j][i] == -1) {
  485.             g.setColor(Color.black);
  486.             g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight);
  487.         }
  488.         else if (layout[j][i] != 0) {
  489.             String numStr = String.valueOf(layout[j][i]);
  490.                
  491.             g.setFont(numFont);
  492.             g.drawString(numStr, tempLeft + 4 , tempTop + 10);
  493.                
  494.         }
  495.                
  496.         // -- put in text if needed
  497.         
  498.         if (layout[j][i] != -1) {
  499.             if (gGuesses[i][j].length() != 0) {
  500.             int sWidth = 0;
  501.             
  502.             if (gGuesses[i][j].equalsIgnoreCase(answers[j][i]) == false)
  503.                 g.setColor(Color.red);
  504.             else
  505.                 g.setColor(Color.black);
  506.             
  507.             sWidth = answerFontMetrics.stringWidth(gGuesses[i][j]);
  508.             g.setFont(answerFont);
  509.             g.drawString( gGuesses[i][j], tempLeft + ((kBlockWidth / 2) - (sWidth / 2)), (tempTop + kBlockHeight) - 6);
  510.             }
  511.             
  512.         }    
  513.         
  514.         }
  515.     }    
  516.     }
  517.  
  518.     /*----------------------------------------------*/
  519.  
  520.     void PaintQuestionArea(Graphics g) {
  521.     Font f = new java.awt.Font("Helvetica", 0, 12);
  522.     Font questionFont = new java.awt.Font("Courier", 0, 24);
  523.     Font questionFont18 = new java.awt.Font("Courier", 0, 18);
  524.     FontMetrics questionFontMetrics = g.getFontMetrics(questionFont);
  525.     
  526.     int viewWidth = kBlocksWide * kBlockWidth;
  527.     int viewHeight = kBlocksHigh * kBlockHeight;
  528.     
  529.     int top = kPadding;
  530.     int left = (size().width / 2) - (viewWidth / 2);
  531.     //g.clipRect(left, top, viewWidth, kQuestionAreaHeight);
  532.     
  533.     g.setColor(Color.white);
  534.     g.fill3DRect(left, top, viewWidth, kQuestionAreaHeight, false);
  535.     
  536.     g.setFont(f);
  537.     String s = new String(    String.valueOf(layout[gBlockMinY][gBlockMinX]));
  538.     s = s.concat(" - ");
  539.     if (gDirection == kAcross)
  540.         s = s.concat("across");
  541.     else
  542.         s = s.concat("down");
  543.     g.drawString(s, left + 5, top + 12);    
  544.     g.setFont(questionFont);
  545.     int fontSize = 24;
  546.     if (gDirection == kAcross) {
  547.         Font userFont = questionFont;
  548.     
  549.         if (questionFontMetrics.stringWidth(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]) > viewWidth - 4) {
  550.         userFont = questionFont18;
  551.         g.setFont(questionFont18);
  552.         }
  553.     
  554.         g.drawString(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]], 
  555.              (size().width / 2) - (g.getFontMetrics().stringWidth(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]) / 2), 
  556.              (top + kQuestionAreaHeight) - 8);
  557.     
  558.     }    
  559.     else {
  560.         Font userFont = questionFont;
  561.     
  562.         if (questionFontMetrics.stringWidth(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]) > viewWidth - 4) {
  563.         userFont = questionFont18;
  564.         g.setFont(questionFont18);
  565.         }
  566.     
  567.         g.drawString(gQuestionsDown[layout[gBlockMinY][gBlockMinX]], 
  568.              (size().width / 2) - (g.getFontMetrics().stringWidth(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]) / 2), 
  569.              (top + kQuestionAreaHeight) - 8);
  570.     }
  571.  
  572.     }
  573.  
  574.     /*----------------------------------------------*/
  575.  
  576.     private boolean InActiveBlock(int x, int y) {
  577.     if (x < gBlockMinX)
  578.         return(false);
  579.     if (x > gBlockMaxX)
  580.         return(false);
  581.     if (y < gBlockMinY)
  582.         return(false);
  583.     if (y > gBlockMaxY)
  584.         return(false);
  585.     
  586.     return(true);
  587.     }
  588.  
  589.     /*----------------------------------------------*/
  590.  
  591.     private void SetActiveBlock(int x, int y, int direction) {
  592.     int tempx;
  593.     int tempy;
  594.  
  595.     gOldBlockMinY    = gBlockMinY;
  596.     gOldBlockMaxY     = gBlockMaxY;
  597.     gOldBlockMinX = gBlockMinX;
  598.     gOldBlockMaxX    = gBlockMaxX;
  599.  
  600.  
  601.     if (direction == kAcross) {
  602.         gBlockMinY = y;
  603.         gBlockMaxY = y;
  604.         tempx = x;
  605.         while (tempx > 0 && layout[y][tempx] != -1) {
  606.         tempx--;
  607.         }
  608.         if (tempx > 0)
  609.         gBlockMinX = tempx + 1;
  610.         else {
  611.         if (layout[y][0] == -1)
  612.             gBlockMinX = 1;
  613.         else
  614.             gBlockMinX = 0;
  615.         }
  616.  
  617.         tempx = x;
  618.         while (tempx < kBlocksWide && layout[y][tempx] != -1)
  619.         {
  620.         tempx++;
  621.         }
  622.         gBlockMaxX = tempx -1;
  623.     }
  624.     else {
  625.         gBlockMinX = x;
  626.         gBlockMaxX = x;
  627.         tempy = y;
  628.         while (tempy > 0 && layout[tempy][x] != -1) {
  629.         tempy--;
  630.         }
  631.         if (tempy > 0)
  632.         gBlockMinY = tempy + 1;
  633.         else {
  634.         if (layout[0][x] == -1)
  635.             gBlockMinY = 1;
  636.         else
  637.             gBlockMinY = 0;
  638.         }
  639.  
  640.         tempy = y;
  641.         while (tempy < kBlocksHigh && layout[tempy][x] != -1) {
  642.         tempy++;
  643.         }
  644.         gBlockMaxY = tempy -1;
  645.     }    
  646.     }
  647.  
  648.     /*----------------------------------------------*/
  649.  
  650.     public void update(Graphics g)  {
  651.     if (clipLeft != -1 && clipTop != -1) {
  652.         //g.clipRect(clipLeft, clipTop, clipWidth, clipHeight);
  653.         clipLeft = clipTop = clipWidth = clipHeight = -1;
  654.     }
  655.  
  656.     if (gChangedActiveAreaFlag == false && gUpdateActiveAreaFlag == false) {        
  657.         paint(g);
  658.         return;
  659.     }
  660.  
  661.     if (gChangedActiveAreaFlag == true) {
  662.         PaintQuestionArea(g);
  663.         PaintWord(g, gOldBlockMinX, gOldBlockMaxX, gOldBlockMinY, gOldBlockMaxY);
  664.         PaintWord(g, gBlockMinX, gBlockMaxX, gBlockMinY, gBlockMaxY);
  665.         gChangedActiveAreaFlag = false;
  666.         return;
  667.     }
  668.  
  669.     //-----------------------------------------------
  670.     
  671.     if (gUpdateActiveAreaFlag == true) {
  672.         gUpdateActiveAreaFlag = false;
  673.         PaintWord(g, gBlockMinX, gBlockMaxX, gBlockMinY, gBlockMaxY);
  674.         return;
  675.     }
  676.     
  677.     }
  678.  
  679.     /*----------------------------------------------*/
  680.  
  681.     private void beep() {
  682.     play(getCodeBase(), "nope.au");
  683.     }
  684.  
  685.     /*----------------------------------------------*/
  686.  
  687.     public boolean mouseDown(java.awt.Event evt, int x, int y) {
  688.     int viewWidth = kBlocksWide * kBlockWidth;
  689.     int left = (size().width / 2) - (viewWidth / 2);
  690.     int top = (kPadding * 2) + kQuestionAreaHeight; 
  691.  
  692.     requestFocus();
  693.  
  694.     if (x < left)
  695.         return false;
  696.     if (y < top)
  697.         return false;
  698.     
  699.     int j = y - top;
  700.     j /= kBlockHeight;
  701.     
  702.     int i = x - left;
  703.     i /= kBlockWidth;
  704.     
  705.     
  706.     if (i >= 0 && i < kBlocksWide && j >= 0 && j < kBlocksHigh) {
  707.         if (layout[j][i] != -1) {
  708.         gCurX = i;
  709.         gCurY = j;
  710.         if (InActiveBlock(i, j)) {
  711.             gUpdateActiveAreaFlag = true;
  712.             repaint();
  713.         }
  714.         else {
  715.             SetActiveBlock(i, j, gDirection);
  716.             gChangedActiveAreaFlag = true;
  717.             repaint();
  718.         }
  719.         return true;
  720.         }
  721.     }
  722.     return true;
  723.     }
  724.  
  725.     /*----------------------------------------------*/
  726.  
  727.     public boolean mouseUp(java.awt.Event evt, int x, int y) {
  728.     requestFocus();
  729.     return true;
  730.     }
  731.  
  732.     /*----------------------------------------------*/
  733.  
  734.     public boolean mouseDrag(java.awt.Event evt, int x, int y) {
  735.     requestFocus();
  736.     return true;
  737.     }
  738.  
  739.  
  740.     /*----------------------------------------------*/
  741.  
  742.     public boolean mouseExit(java.awt.Event evt) {
  743.     return true;
  744.     }
  745.  
  746.     /*----------------------------------------------*/
  747.  
  748.     public boolean mouseEnter(java.awt.Event evt) {
  749.     requestFocus();
  750.     return true;
  751.     }
  752.  
  753.     /*----------------------------------------------*/
  754.  
  755.     public boolean mouseMove(java.awt.Event evt, int x, int y) {
  756.     requestFocus();
  757.     return true;
  758.     }
  759.  
  760.     /*----------------------------------------------*/
  761.  
  762.     public boolean keyDown(java.awt.Event evt, int key) {
  763.  
  764.     if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z')) {
  765.         char charArray[] = new char[1];
  766.     
  767.         charArray[0] = (char)key;
  768.     
  769.         gGuesses[gCurX][gCurY] = new String(charArray); 
  770.         gGuesses[gCurX][gCurY] = gGuesses[gCurX][gCurY].toUpperCase();
  771.     
  772.     
  773.         if (gDirection == kAcross) {
  774.         if (gCurX < kBlocksWide - 1 && layout[gCurY][gCurX+1] != -1)
  775.             gCurX++;
  776.         }
  777.         else {
  778.         if (gCurY < kBlocksHigh - 1 && layout[gCurY + 1][gCurX] != -1)
  779.             gCurY++;
  780.         }
  781.         gUpdateActiveAreaFlag = true;
  782.         repaint();
  783.         return true;
  784.     }
  785.  
  786.     switch ((char)key) {
  787.       case ' ':
  788.         ChangeDirection();
  789.         gChangedActiveAreaFlag = true;
  790.         repaint();
  791.         break;
  792.       case 0x08:
  793.         if (gGuesses[gCurX][gCurY] != "") {
  794.         gGuesses[gCurX][gCurY] = "";
  795.         gUpdateActiveAreaFlag = true;
  796.         repaint();
  797.         }
  798.         else {
  799.         if (gDirection == kAcross) {
  800.             if (gCurX != 0 && layout[gCurY][gCurX-1] != -1) {
  801.             gCurX--;
  802.             gGuesses[gCurX][gCurY] = "";
  803.             gUpdateActiveAreaFlag = true;
  804.             repaint();
  805.             }
  806.         }
  807.         else {
  808.             if (gCurY != 0 && layout[gCurY - 1][gCurX] != -1) {
  809.             gCurY--;
  810.             gGuesses[gCurX][gCurY] = "";
  811.             gUpdateActiveAreaFlag = true;
  812.             repaint();
  813.             }
  814.         }
  815.         }
  816.         break;
  817.       default:
  818.         beep();
  819.         break;
  820.     }
  821.     return true;
  822.     }
  823.  
  824.  
  825.     /*----------------------------------------------*/
  826.  
  827.     int random(int max) {
  828.     return (int)Math.floor(Math.random() * max);
  829.     }
  830.  
  831.     /*----------------------------------------------*/
  832.  
  833.     boolean PtInRect(int x, int y, int left, int top, int right, int bottom) {
  834.     if (x < left)
  835.         return(false);
  836.     
  837.     if (x > right)
  838.         return(false);
  839.     
  840.     if (y < top)
  841.         return(false);
  842.     
  843.     if (y > bottom)
  844.         return(false);
  845.     
  846.     return(true);
  847.     }
  848.  
  849.     /*----------------------------------------------*/
  850.  
  851.     void ChangeDirection() {
  852.     if (gDirection == kDown) {
  853.         gDirection = kUp;    
  854.     }
  855.     else
  856.         gDirection = kDown;
  857.     SetActiveBlock(gCurX, gCurY, gDirection);    
  858.     }
  859.  
  860.  
  861. }
  862.  
  863.